home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / emac16ds.zip / MEMORY.ASM < prev    next >
Assembly Source File  |  1991-08-03  |  12KB  |  624 lines

  1. ;History:462,1
  2. ;Thu Feb 22 23:40:41 1990 make buffer_modified into a bitmap.
  3. ;09-07-88 22:03:44 remove public margin
  4. ;04-07-88 00:08:22 remember to set buffer-modified on xlat_to_mark
  5. ;03-30-88 21:22:37 add xlat_to_mark
  6. ;11-16-87 23:13:40 move calculations involving memsize into buffers.asm
  7. ;11-15-87 00:04:12 call buffer_free.
  8. ;11-14-87 23:09:22 move toptop..botbot out of memory.
  9. ;07-15-87 23:31:17 get rid of dump_bufseg
  10. ;07-13-87 22:53:52 move init_memory to mintprim.asm
  11.  
  12. debugging    equ    0
  13.  
  14.     .xlist
  15.     include    emacs.def
  16.  
  17. HT    equ    09h
  18. LF    equ    0ah
  19. CR    equ    0dh
  20. LINENEW    equ    CR+LF*256    ;the way a newline is stored in memory.
  21.  
  22. bufseg    segment    public
  23.  
  24.     extrn    toptop: word
  25.     extrn    topbot: word
  26.     extrn    bottop: word
  27.     extrn    botbot: word
  28.  
  29.     public    linecount, linesbefore
  30. linecount    dw    ?
  31. linesbefore    dw    ?
  32.  
  33.     public    buffer_modified
  34. buffer_modified    db    ?
  35.  
  36.     extrn    bufseg_size: byte
  37.  
  38. bufseg    ends
  39.  
  40. data    segment    byte public
  41.  
  42. ;the following externs are in 'buffers'
  43.     extrn    textseg: word
  44.  
  45. insert_ds    dw    ?
  46.  
  47. data    ends
  48.  
  49. b_struc    struc
  50. b    db    ?
  51. b_struc    ends
  52.  
  53. w_struc    struc
  54. w    dw    ?
  55. w_struc    ends
  56.  
  57. byte_ptr    label    byte
  58.  
  59. code    segment    byte public
  60. ;all the routines in this segment are entered with ds=data, es=data
  61.     assume    cs:code, ds:data, es:data
  62.  
  63. ;the following externs are in 'marks'
  64.     extrn    init_marks: near
  65.     extrn    get_mark: near
  66.     extrn    adjust_marks_del: near
  67.     extrn    adjust_marks_ins: near
  68.  
  69. ;the following externs are in 'redisp'
  70.     extrn    prevline: near
  71.     extrn    nextline: near
  72.     extrn    compute_one: near
  73.  
  74.  
  75.     public    count_lines
  76. count_lines:
  77.     push    ds
  78.     mov    ds,textseg
  79.     call    count_lines$
  80.     pop    ds
  81.     ret
  82.  
  83.     public    del_to_mark
  84. del_to_mark:
  85.     push    ds
  86.     mov    ds,textseg
  87.     call    del_to_mark$
  88.     pop    ds
  89.     ret
  90.  
  91.  
  92.     public    read_mark
  93. read_mark:
  94.     mov    ds,textseg
  95.     call    read_mark$
  96.     ret
  97.  
  98.  
  99.     public    goto_mark
  100. goto_mark:
  101.     push    ds
  102.     mov    ds,textseg
  103.     call    goto_mark$
  104.     pop    ds
  105.     ret
  106.  
  107.  
  108.     public    xlat_to_mark
  109. xlat_to_mark:
  110.     push    ds
  111.     mov    ds,textseg
  112.     call    xlat_to_mark$
  113.     pop    ds
  114.     ret
  115.  
  116.  
  117.     public    insert_string
  118. insert_string:
  119.     push    ds
  120.     mov    ax,es            ;use data for insert_ds.
  121.     mov    ds,textseg
  122.     call    insert_string$
  123.     pop    ds
  124.     ret
  125.  
  126.  
  127.     public    set_column
  128. set_column:
  129.     push    ds
  130.     mov    ds,textseg
  131.     call    set_column$
  132.     pop    ds
  133.     ret
  134.  
  135.  
  136.     public    set_line
  137. set_line:
  138.     push    ds
  139.     mov    ds,textseg
  140.     call    set_line$
  141.     pop    ds
  142.     ret
  143.  
  144.  
  145.     public    compute_cursor
  146. compute_cursor:
  147. ;exit with dx=column.
  148.     push    ds
  149.     mov    ds,textseg
  150.     call    compute_cursor$
  151.     pop    ds
  152.     ret
  153.  
  154.  
  155.     public    store_buffer_modified
  156. store_buffer_modified:
  157.     push    ds
  158.     mov    ds,textseg
  159.     assume    ds:bufseg
  160.     mov    buffer_modified,al
  161.     pop    ds
  162.     assume    ds:data
  163.     ret
  164.  
  165.  
  166.     public    read_linecount
  167. read_linecount:
  168.     mov    bx,offset linecount
  169.     jmp    short read_variable
  170.     public    read_linesbefore
  171. read_linesbefore:
  172.     mov    bx,offset linesbefore
  173.     jmp    short read_variable
  174.     public    read_buffer_modified
  175. read_buffer_modified:
  176.     mov    bx,offset buffer_modified
  177. read_variable:
  178.     push    ds
  179.     mov    ds,textseg
  180.     assume    ds:bufseg
  181.     mov    ax,bufseg:[bx]
  182.     pop    ds
  183.     assume    ds:data
  184.     ret
  185.  
  186.  
  187.     public    file_size
  188. file_size:
  189. ;exit with ax=size of the current buffer in bytes.
  190.     mov    ds,textseg
  191.     assume    ds:bufseg
  192.     mov    ax,topbot
  193.     sub    ax,toptop
  194.     add    ax,botbot
  195.     sub    ax,bottop
  196.     push    es
  197.     pop    ds
  198.     assume    ds:data
  199.     ret
  200.  
  201.  
  202. code    ends
  203.  
  204. code    segment    byte public
  205. ;all the code in this segment is entered with ds=bufseg, es=data
  206.     assume    cs:code, ds:bufseg, es:data
  207.  
  208. ;the following externs are in 'redisp'
  209.     extrn    paint_window: near
  210.     extrn    trash_line: near
  211.     extrn    window_insert: near
  212.     extrn    window_delete: near
  213.     extrn    up_lines: near
  214.     extrn    down_lines: near
  215.  
  216.     public    init_vars$
  217. init_vars$:
  218.     mov    bx,offset bufseg_size+2
  219.     mov    [bx-02].w,LINENEW
  220.     mov    toptop,bx
  221.     mov    topbot,bx
  222.     mov    bottop,bx
  223.     mov    botbot,bx
  224.     mov    linecount,0
  225.     mov    linesbefore,0
  226.     mov    buffer_modified,0
  227.     ret
  228.  
  229.  
  230.     extrn    buffer_free: near
  231.  
  232.     public    insert_string$
  233. insert_string$:
  234. ;enter with si,cx describing the string to insert, ax=segment of string.
  235. ;exit with cy if there isn't enough room to insert the entire string.
  236.     jcxz    insert_string_1
  237.     mov    es,ax            ;put it where we need it.
  238.     mov    ax,ds
  239.     call    buffer_free
  240.     mov    ss:insert_ds,es        ;remember what it is now.
  241.     push    ss
  242.     pop    es
  243.     jc    insert_string_4        ;no - give error.
  244.     or    buffer_modified,5
  245. insert_string_2:
  246.     push    ds
  247.     mov    ds,insert_ds
  248.     mov    ax,ds:[si]        ;get an entire word, even though we might use only the low byte.
  249.     pop    ds
  250.     cmp    ax,LINENEW    ;newline?
  251.     jne    insert_string_3        ;no.
  252.     cmp    cx,2            ;must be at least two chars left.
  253.     jb    insert_string_3        ;no - can't be newline.
  254.     push    cx
  255.     push    si
  256.     call    inscrlf
  257.     pop    si
  258.     pop    cx
  259.     add    si,2
  260.     dec    cx
  261.     loop    insert_string_2
  262.     jmp    short insert_string_1
  263. insert_string_3:
  264.     push    cx
  265.     push    si
  266.     call    insone
  267.     pop    si
  268.     pop    cx
  269.     inc    si
  270.     loop    insert_string_2
  271. insert_string_1:
  272.     clc
  273.     ret
  274. insert_string_4:
  275.     stc
  276.     ret
  277.  
  278.  
  279. insone:
  280.     cmp    al,CR
  281.     jne    insone_1
  282.     mov    bx,bottop
  283.     cmp    [bx].b,LF
  284.     jne    inschar
  285.     inc    bottop
  286.     jmp    short insone_2
  287. insone_1:
  288.     cmp    al,LF
  289.     jne    inschar
  290.     mov    bx,topbot
  291.     cmp    [bx-01].b,CR
  292.     jne    inschar
  293.     dec    topbot
  294. insone_2:
  295.     mov    ax,1
  296.     call    adjust_marks_del
  297.     call    inscrlf
  298.     ret
  299.  
  300. inschar:
  301. ;insert the character in al at the point.
  302. ;unless there is no room.
  303.     mov    bx,topbot
  304.     cmp    bx,bottop
  305.     jae    inschar_1
  306.     push    ax
  307.     mov    ax,1
  308.     call    adjust_marks_ins
  309.     pop    ax
  310.     mov    di,topbot
  311.     mov    [di],al
  312.     inc    di
  313.     mov    topbot,di
  314.     call    trash_line
  315. inschar_1:
  316.     ret
  317.  
  318.  
  319. inscrlf:
  320.     mov    bx,topbot
  321.     inc    bx
  322.     cmp    bx,bottop
  323.     jae    inscrlf_3
  324.  
  325.     mov    ax,2
  326.     call    adjust_marks_ins
  327.  
  328.     mov    di,topbot
  329.     mov    [di].w,LINENEW
  330.     add    di,2
  331.     mov    topbot,di
  332.  
  333.     inc    linesbefore
  334.     inc    linecount
  335.  
  336.     call    window_insert        ;say that we inserted a line here.
  337.  
  338. inscrlf_3:
  339.     ret
  340.  
  341.  
  342. del_to_mark$:
  343.     call    get_mark
  344.     jcxz    del_to_mark_4_j_1
  345.     jc    del_to_mark_2        ;go if point>mark
  346.     push    bottop
  347.     call    move_point_backward    ;swap point and mark (sort of).
  348.     pop    si            ;pushed as bottop.
  349. del_to_mark_2:
  350.     or    buffer_modified,5
  351.     mov    di,toptop        ;are we at the beginning of the file?
  352.     cmp    di,topbot
  353.     jne    del_to_mark_1        ;no
  354.     cmp    si,botbot        ;deleting to the end of the file?
  355.     jne    del_to_mark_1        ;no
  356.     mov    ax,si
  357.     sub    ax,bottop        ;compute the number of chars deleted.
  358.     mov    bottop,si        ;no characters left.
  359.     call    adjust_marks_del
  360.     mov    linecount,0        ;no lines left.
  361.     call    paint_window        ;trash the window.
  362. del_to_mark_4_j_1:
  363.     jmp    short del_to_mark_4    ;now exit.
  364. del_to_mark_1:
  365.     mov    bp,si            ;save the char that we delete to.
  366.     mov    ax,si            ;compute the number of chars.
  367.     sub    ax,bottop
  368.     call    adjust_marks_del    ;fix up the marks first.
  369.     mov    si,bottop        ;get the -> first char to delete.
  370. del_to_mark_3:
  371.     cmp    [si].w,LINENEW        ;a newline?
  372.     jne    del1_1            ;no - just skip this char.
  373.     inc    si            ;extra inc to skip past the CR.
  374.     dec    linecount        ;one less line.
  375.     call    window_delete        ;fix up the window.
  376. del1_1:
  377.     inc    si
  378.     cmp    bp,si
  379.     jne    del_to_mark_3
  380.     mov    bottop,si
  381.     call    trash_line
  382. ;now check for a newly created newline.
  383.     mov    bx,topbot
  384.     cmp    [bx-1].b,CR
  385.     jne    del_to_mark_4
  386.     mov    bx,bottop
  387.     cmp    [bx].b,LF
  388.     jne    del_to_mark_4
  389. ;get rid of the LF and CR seperately so that any mark that points to either
  390. ;  one will point to the newline.
  391.     inc    bottop            ;get rid of the LF
  392.     mov    ax,1
  393.     call    adjust_marks_del
  394.     dec    topbot            ;get rid of the CR
  395.     mov    ax,1
  396.     call    adjust_marks_del
  397.     call    inscrlf            ;now insert a newline.
  398. del_to_mark_4:
  399.     ret
  400.  
  401.  
  402. xlat_to_mark$:
  403. ;enter with al =mark, bx,dx ->translate string.
  404.     push    bx
  405.     push    dx
  406.     call    read_mark$
  407.     pop    dx
  408.     pop    bx
  409.     jcxz    xlat_to_mark_2        ;quit if no chars in the region.
  410.     or    buffer_modified,5
  411. xlat_to_mark_1:
  412.     cmp    word ptr [si],LINENEW    ;is this a newline?
  413.     jne    xlat_to_mark_3
  414.     add    si,2            ;yes - skip it.
  415.     dec    cx
  416.     jmp    short xlat_to_mark_4
  417. xlat_to_mark_3:
  418.     lodsb                ;translate the character.
  419.     cmp    al,dl            ;is this character in the translate char?
  420.     jae    xlat_to_mark_4        ;yes - it is.
  421.     xlat    es:[bx]
  422.     mov    [si-1],al
  423. xlat_to_mark_4:
  424.     loop    xlat_to_mark_1
  425. xlat_to_mark_2:
  426.     call    paint_window        ;trash the window.
  427.     ret
  428.  
  429.  
  430.     public    goto_mark$
  431. goto_mark$:
  432.     call    get_mark
  433.     jcxz    goto_mark_1
  434.     jnc    goto_mark_2
  435.     call    move_point_forward
  436.     jmp    short goto_mark_1
  437. goto_mark_2:
  438.     call    move_point_backward
  439. goto_mark_1:
  440.     ret
  441.  
  442.  
  443.     public    read_mark$
  444. read_mark$:
  445.     call    get_mark
  446.     jnc    read_mark_1
  447.     mov    si,bottop
  448. read_mark_1:
  449.     ret
  450.  
  451.  
  452. move_point_backward:
  453.     mov    si,topbot
  454.     mov    di,bottop
  455.     push    es
  456.     push    ds
  457.     pop    es
  458.     std
  459.     dec    si
  460.     dec    di
  461.     push    cx
  462.     rep    movsb
  463.     pop    cx
  464.     inc    si
  465.     inc    di
  466.     cld
  467.     pop    es
  468.     mov    topbot,si
  469.     mov    bottop,di
  470.     call    count_lines$
  471.     sub    linesbefore,bx
  472.     call    up_lines
  473.     ret
  474.  
  475.  
  476. move_point_forward:
  477.     mov    si,bottop
  478.     mov    di,topbot
  479.     push    di
  480.     push    cx
  481.     push    es
  482.     push    ds
  483.     pop    es
  484.     movmem
  485.     pop    es
  486.     mov    bottop,si
  487.     mov    topbot,di
  488.     pop    cx
  489.     pop    di
  490.     call    count_lines$
  491.     add    linesbefore,bx
  492.     call    down_lines
  493.     ret
  494.  
  495.  
  496. count_lines$:
  497. ;count the number of newlines contained in the text described by ds:di,cx.
  498.     push    es
  499.     push    ds
  500.     pop    es
  501.     mov    bx,0
  502. count_lines_1:
  503.     mov    al,CR
  504.     repnz    scasb
  505.     jcxz    count_lines_2
  506.     cmp    [di].b,LF
  507.     jne    count_lines_1
  508.     inc    bx
  509.     jmp    count_lines_1
  510. count_lines_2:
  511.     pop    es
  512.     ret
  513.  
  514.  
  515.     public    set_line$
  516. set_line$:
  517. ;given a line number in ax, move to that line.
  518.     dec    ax            ;linesbefore is zero based.
  519.     or    ax,ax            ;if negative, use zero.
  520.     jns    set_line_0
  521.     xor    ax,ax
  522. set_line_0:
  523.     sub    ax,linesbefore
  524.     je    set_line_1        ;go if we're already on that line.
  525.     jb    set_line_2        ;go if we're after that line.
  526.     mov    cx,ax
  527.     mov    si,bottop
  528. set_line_4:
  529.     call    nextline
  530.     loopne    set_line_4
  531.     mov    cx,si            ;compute the number of characters.
  532.     sub    cx,bottop
  533.     call    move_point_forward
  534.     jmp    short set_line_1
  535. set_line_2:
  536.     neg    ax            ;ax is the number of lines to move.
  537.     mov    cx,ax
  538.     mov    si,topbot
  539.     cmp    [si-2].w,LINENEW    ;are we at the beginning of a line?
  540.     je    set_line_3        ;yes.
  541.     call    prevline        ;no, go to the beginning of the line.
  542. set_line_3:
  543.     call    prevline
  544.     loopne    set_line_3
  545.     mov    cx,topbot        ;compute the number of characters.
  546.     sub    cx,si
  547.     call    move_point_backward
  548. set_line_1:
  549.     ret
  550.  
  551.  
  552. set_column$:
  553. ;given a column number in ax, move to that column.
  554.     mov    bx,ax        ;save the column number in bx.
  555.     dec    bx        ;columns are zero based.
  556.     mov    si,topbot
  557.     jmp    short set_column$_2
  558. set_column$_1:
  559.     dec    si
  560. set_column$_2:
  561.     cmp    [si-2].w,LINENEW
  562.     jne    set_column$_1
  563. ;now move over to the point, counting the size of characters on the way.
  564.     mov    dx,0
  565.     mov    cx,topbot
  566.     sub    cx,si
  567.     jcxz    set_column$_3
  568. set_column$_4:
  569.     cmp    dx,bx        ;are we at or past the desired column?
  570.     jae    set_column$_6    ;yes - move the point backward.
  571.     lodsb
  572.     call    compute_one
  573.     loop    set_column$_4
  574. set_column$_3:
  575. ;the desired column is somewhere after the point.
  576.     mov    si,bottop
  577. set_column$_7:
  578.     cmp    dx,bx        ;are we at or past the desired column?
  579.     jae    set_column$_5    ;yes - go to the column.
  580.     cmp    si,botbot    ;did we hit eof?
  581.     je    set_column$_5    ;yes - this is as close as we can get.
  582.     cmp    [si].w,LINENEW    ;are we at the end of the line?
  583.     je    set_column$_5    ;yes - this is as close as we can get.
  584.     lodsb            ;compute the next character.
  585.     call    compute_one
  586.     jmp    set_column$_7
  587. set_column$_5:
  588.     mov    cx,si
  589.     sub    cx,bottop
  590.     call    move_point_forward
  591.     ret
  592. set_column$_6:
  593.     call    move_point_backward
  594.     ret
  595.  
  596.  
  597.     public    compute_cursor$
  598. compute_cursor$:
  599. ;return the column in dx.
  600. ;find the beginning of this line.
  601.     mov    si,topbot
  602.     jmp    short compute_cursor$_2
  603. compute_cursor$_1:
  604.     dec    si
  605. compute_cursor$_2:
  606.     cmp    [si-2].w,LINENEW
  607.     jne    compute_cursor$_1
  608. ;now move over to the point, counting the size of characters on the way.
  609.     mov    dx,0
  610.     mov    cx,topbot
  611.     sub    cx,si
  612.     jcxz    compute_cursor$_3
  613. compute_cursor$_4:
  614.     lodsb
  615.     call    compute_one
  616.     loop    compute_cursor$_4
  617. compute_cursor$_3:
  618.     ret
  619.  
  620.  
  621. code    ends
  622.  
  623.     end
  624.